package com.jplus.core.utill.clazz;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Properties;

import com.jplus.core.utill.JUtil;

/**
 * 默认类扫描器<br>
 * 有冗余，需要改进
 */
public class ClassSearchUtil {

	private static Class<?> castFile2Cls(String fileName) {
		// 文件名转 class,不初始化
		return ClassUtil.loadClass(fileName, false);
	}

	/**
	 * 获取包名下所有类
	 */
	public static List<Class<?>> getList(String packageName) {
		return new ClassTemplate<Class<?>>() {
			@Override
			public Class<?> checkAndAdd(String packageName, String fileName, String suffix) {
				if (suffix.equalsIgnoreCase(".class")) {
					Class<?> cls = castFile2Cls(packageName + "." + fileName);
					return cls;
				}
				return null;
			}
		}.getFileList(packageName);
	}

	/**
	 * 获取包名下 有指定注解的所有类
	 */
	public static List<Class<?>> getListByAnnotation(String packageName,
			final Class<? extends Annotation> annotationClass) {
		return new ClassTemplate<Class<?>>() {
			@Override
			public Class<?> checkAndAdd(String packageName, String fileName, String suffix) {
				if (suffix.equalsIgnoreCase(".class")) {
					String classPath = packageName.isEmpty() ? fileName : packageName + "." + fileName;
					Class<?> cls = castFile2Cls(classPath);
					if (!cls.isAnnotation()) {
						if (ClassUtil.hasAnnotation(cls, annotationClass)) {
							return cls;
						}
					}
				}
				return null;
			}
		}.getFileList(packageName);
	}

	/**
	 * 获取包名下 继承/实现某类的所有实现类,不包含自己
	 */
	public static List<Class<?>> getListBySuper(String packageName, final Class<?> superClass) {
		return new ClassTemplate<Class<?>>() {
			@Override
			public Class<?> checkAndAdd(String packageName, String fileName, String suffix) {
				if (suffix.equalsIgnoreCase(".class")) {
					String classPath = packageName.isEmpty() ? fileName : packageName + "." + fileName;
					Class<?> cls = castFile2Cls(classPath);
					if (superClass.isAssignableFrom(cls) && !superClass.equals(cls)) {
						return cls;
					}
				}
				return null;
			}
		}.getFileList(packageName);
	}

	/**
	 * 获取包名下 you指定注解的所有类[满足一个注解即可]
	 */
	public static List<Class<?>> getListByAnnotation(String packageName,
			final List<Class<? extends Annotation>> annotationClass, final boolean isRecursive) {
		return new ClassTemplate<Class<?>>() {
			@Override
			public Class<?> checkAndAdd(String packageName, String fileName, String suffix) {
				if (suffix.equalsIgnoreCase(".class")) {
					String classPath = packageName.isEmpty() ? fileName : packageName + "." + fileName;
					Class<?> cls = castFile2Cls(classPath);
					if (!cls.isAnnotation()) {
						for (Class<? extends Annotation> cl : annotationClass) {
							if (ClassUtil.hasAnnotation(cls, cl)) {
								return cls;
							}
						}
					}
				}
				return null;
			}
		}.getFileList(packageName);
	}

	/**
	 * 获取包名下 继承/实现某类的所有实现类,不包含自己。[满足一个注解即可]
	 */
	public static List<Class<?>> getListBySuper(String packageName, final List<Class<?>> superClass) {
		return new ClassTemplate<Class<?>>() {
			@Override
			public Class<?> checkAndAdd(String packageName, String fileName, String suffix) {
				if (suffix.equalsIgnoreCase(".class")) {
					String classPath = packageName.isEmpty() ? fileName : packageName + "." + fileName;
					Class<?> cls = castFile2Cls(classPath);
					for (Class<?> cl : superClass) {
						if (cl.isAssignableFrom(cls) && !cl.equals(cls)) {
							return cls;
						}
					}
				}
				return null;
			}
		}.getFileList(packageName);
	}

	/**
	 * 获取包名下 所有的xml文件
	 */
	public static List<File> getXmlFileList(String packageName) {
		return new ClassTemplate<File>() {
			@Override
			public File checkAndAdd(String packageName, String fileName, String suffix) {
				if (suffix.equalsIgnoreCase(".xml")) {
					packageName = packageName.replaceAll("\\.", "/");
					String filePath = JUtil
							.formatPath(ClassUtil.getClassPath() + packageName + "/" + fileName + suffix);
					File file = new File(filePath);
					return (file);
				}
				return null;
			}
		}.getFileList(packageName);
	}

	public static List<Class<?>> getListIsInterface(String packageName) {
		return new ClassTemplate<Class<?>>() {
			@Override
			public Class<?> checkAndAdd(String packageName, String fileName, String suffix) {
				if (suffix.equalsIgnoreCase(".class")) {
					String classPath = packageName.isEmpty() ? fileName : packageName + "." + fileName;
					Class<?> cls = castFile2Cls(classPath);
					if (cls.isInterface())
						return (cls);
				}
				return null;
			}
		}.getFileList(packageName);
	}

	public static Properties getProperties(String file) {
		return new ClassTemplate<Properties>() {
			@Override
			public Properties checkAndAdd(String packageName, String fileName, String suffix) {
				if (suffix.equalsIgnoreCase(".properties")) {
					try {
						Properties prop = new Properties();
//						logger.warn("#" + fileName + suffix);
						InputStream in = ClassLoader.getSystemResourceAsStream(fileName + suffix);// 读jar包根目录下的文件
						if (in != null) {
							prop.load(in);
							return prop;
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				return null;
			}
		}.getFile(file);

	}
}
